#ifndef __HASH_H
#define __HASH_H
#include "stdtype.h"

/// ------------------------------------------------------------------------ murmur3

mx_uint32_t hash_murmur3_32 (mx_uint8_pt data, mx_uint32_t len, mx_uint32_t seed);

/// ------------------------------------------------------------------------ xor

mx_uint8_t hash_xor8 (mx_uint8_pt data, mx_usize_t len);
mx_uint16_t hash_xor16_le (mx_uint8_pt data, mx_usize_t len);
mx_uint16_t hash_xor16_be (mx_uint8_pt data, mx_usize_t len);

/// ------------------------------------------------------------------------ crc

/* the parametric model of CRC8, for `hash_crc8cfg_t` initialization */
#define CRC8CFG_DEF mx_false, mx_false, 0x07, 0x00, 0x00
#define CRC8CFG_ITU mx_false, mx_false, 0x15, 0x00, 0x00
#define CRC8CFG_ROHC mx_true, mx_true, 0x15, 0xff, 0x00
#define CRC8CFG_MAXIM mx_true, mx_true, 0x31, 0x00, 0x00

/* the model configuration of CRC8 */
typedef struct
{
    mx_bool_t refin;        // input value reflect
    mx_bool_t refout;       // output value reflect
    mx_uint8_t poly;        // polynomial value
    mx_uint8_t init;        // initialize value
    mx_uint8_t xorout;      // output value XOR operations
} hash_crc8cfg_t, *hash_crc8cfg_pt;

/* CRC8 algorithm */
mx_uint8_t hash_crc8 (hash_crc8cfg_pt pcfg, mx_uint8_pt data, mx_usize_t len);

/* the parametric model of CRC16, for `hash_crc16cfg_t` initialization */
#define CRC16CFG_IBM mx_true, mx_true, 0x8005, 0x0000, 0x0000
#define CRC16CFG_MAXIM mx_true, mx_true, 0x8005, 0x0000, 0xffff
#define CRC16CFG_USB mx_true, mx_true, 0x8005, 0xffff, 0xffff
#define CRC16CFG_MODBUS mx_true, mx_true, 0x8005, 0xffff, 0x0000
#define CRC16CFG_CCITT mx_true, mx_true, 0x1021, 0x0000, 0x0000
#define CRC16CFG_XMODEM mx_false, mx_false, 0x1021, 0x0000, 0x0000
#define CRC16CFG_DNP mx_true, mx_true, 0x3d65, 0x0000, 0xffff

/* the model configuration of CRC16 */
typedef struct
{
    mx_bool_t refin;        // input value reflect
    mx_bool_t refout;       // output value reflect
    mx_uint16_t poly;       // polynomial value
    mx_uint16_t init;       // initialize value
    mx_uint16_t xorout;     // output value XOR operations
} hash_crc16cfg_t, *hash_crc16cfg_pt;

/* CRC16 algorithm */
mx_uint16_t hash_crc16 (hash_crc16cfg_pt cfg, mx_uint8_pt data, mx_usize_t len);

/* the parametric model of CRC32, for `hash_crc32cfg_t` initialization */
#define CRC32CFG_DEF mx_true, mx_true, 0x04c11db7, 0xffffffff, 0xffffffff
#define CRC32CFG_MPEG2 mx_false, mx_false, 0x04c11db7, 0xffffffff, 0x00000000

/* the model configuration of CRC32 */
typedef struct
{
    mx_bool_t refin;        // input value reflect
    mx_bool_t refout;       // output value reflect
    mx_uint32_t poly;       // polynomial value
    mx_uint32_t init;       // initialize value
    mx_uint32_t xorout;     // output value XOR operations
} hash_crc32cfg_t, *hash_crc32cfg_pt;

/* CRC32 algorithm */
mx_uint32_t hash_crc32 (hash_crc32cfg_pt cfg, mx_uint8_pt data, mx_usize_t len);

#endif
